using Eno.Application.Dto;
using Eno.Application.Services;
using Eno.Domain.Entity.App;
using Eno.Infrastructure.Tools;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace Eno.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    private readonly UserService _service;
    private readonly ILogService _logService;
    // private readonly ISmsSender _smsSender;

    public UserController(UserService service, ILogService logService)
    {
        _service = service;
        _logService = logService;
    }

    [HttpGet]
    public async Task<IActionResult> ListUser([FromQuery] string? account = null, [FromQuery] bool? isActived = null)
    {
        try
        {
            var users = await _service.SelectUser();
            if (!string.IsNullOrWhiteSpace(account))
            {
                users = users.Where(u => u.Account.Contains(account, StringComparison.OrdinalIgnoreCase));
            }
            if (isActived.HasValue)
            {
                users = users.Where(u => u.IsActived == isActived.Value);
            }
            // 为每个用户查找角色
            var userList = new List<object>();
            foreach (var user in users)
            {
                var roles = await _service.GetUserRolesAsync(user.ID);
                userList.Add(new {
                    user.ID,
                    user.Account,
                    user.Avatar,
                    user.CreatedAt,
                    user.UpdatedAt,
                    user.IsActived,
                    user.DepartmentID,
                    user.Email,
                    user.Phone,
                    user.DisplayName,
                    user.Remarks,
                    roles
                });
            }
            await _logService.LogInfoAsync("查询所有用户", "UserController", new { Count = userList.Count });
            return Ok(Tips<IEnumerable<object>>.Success(userList, "查询所有用户成功"));
        }
        catch (Exception ex)
        {
            await _logService.LogErrorAsync("查询所有用户失败", ex, "UserController");
            return Ok(Tips<IEnumerable<AppUser>>.Fail(Enumerable.Empty<AppUser>()));
        }
    }

    [HttpPut("{guid}")]
    public async Task<IActionResult> UpdateUser(Guid guid, UserDto userDto)
    {
        try
        {
            var number = await _service.EditUserAsync(guid, userDto);
            if (number == 0)
            {
                await _logService.LogWarningAsync("修改用户失败", "UserController", new { UserId = guid, userDto.Account });
                return Ok(Tips<int>.Fail(number));
            }

            await _logService.LogInfoAsync("修改用户成功", "UserController", new { UserId = guid, userDto.Account });
            return Ok(Tips<int>.Success(number, "修改用户成功"));
        }
        catch (Exception ex)
        {
            await _logService.LogErrorAsync("修改用户异常", ex, "UserController", new { UserId = guid });
            return Ok(Tips<string>.Fail("修改失败"));
        }
    }

    [HttpDelete("{guid}")]
    public async Task<IActionResult> DeleteUser(Guid guid)
    {
        try
        {
            var number = await _service.DeleteUserAsync(guid);
            if (number == 0)
            {
                await _logService.LogWarningAsync("删除用户失败", "UserController", new { UserId = guid });
                return Ok(Tips<int>.Fail(number));
            }

            await _logService.LogInfoAsync("删除用户成功", "UserController", new { UserId = guid });
            return Ok(Tips<int>.Success(number, "删除操作成功"));
        }
        catch (Exception ex)
        {
            await _logService.LogErrorAsync("删除用户异常", ex, "UserController", new { UserId = guid });
            return Ok(Tips<string>.Fail("删除失败"));
        }
    }

    [HttpPost]
    public async Task<IActionResult> AdditonUser(UserDto userDto)
    {
        try
        {
            var number = await _service.AddUserAsync(userDto);
            if (number == 0)
            {
                await _logService.LogWarningAsync("新增用户失败", "UserController", new { userDto.Account });
                return Ok(Tips<int>.Fail(number));
            }

            await _logService.LogInfoAsync("新增用户成功", "UserController", new { userDto.Account });
            return Ok(Tips<int>.Success(number, "新增用户操作成功"));
        }
        catch (Exception ex)
        {
            await _logService.LogErrorAsync("新增用户异常", ex, "UserController", new { userDto.Account });
            return Ok(Tips<string>.Fail("新增失败"));
        }
    }

    [HttpGet("{account}")]
    public async Task<IActionResult> GetUserByName(string account)
    {
        try
        {
            var user = await _service.GetUserAccount(account);
            if (user == null)
            {
                await _logService.LogWarningAsync("获取用户失败，用户不存在", "UserController", new { Account = account });
                return Ok(Tips<AppUser?>.Fail(user));
            }

            await _logService.LogInfoAsync("获取用户成功", "UserController", new { Account = account, UserId = user.ID });
            return Ok(Tips<AppUser?>.Success(user, $"获取{account}用户成功"));
        }
        catch (Exception ex)
        {
            await _logService.LogErrorAsync("获取用户异常", ex, "UserController", new { Account = account });
            return Ok(Tips<string>.Fail("获取失败"));
        }
    }

    [HttpGet("profile")]
    [Microsoft.AspNetCore.Authorization.Authorize]
    public async Task<IActionResult> GetCurrentUserProfile()
    {
        try
        {
            // 从JWT token中获取用户账号
            var account = User.FindFirst(ClaimTypes.Name)?.Value;
            if (string.IsNullOrEmpty(account))
            {
                await _logService.LogWarningAsync("获取当前用户信息失败，token中无用户信息", "UserController");
                return Ok(Tips<object>.Fail(new object(), 3474, "未找到用户信息"));
            }

            var user = await _service.GetUserAccount(account);
            if (user == null)
            {
                await _logService.LogWarningAsync("获取当前用户信息失败，用户不存在", "UserController", new { Account = account });
                return Ok(Tips<object>.Fail(new object(), 3474, "用户不存在"));
            }

            var roles = await _service.GetUserRolesAsync(user.ID);

            // 不返回敏感信息
            var userInfo = new
            {
                user.ID,
                user.Account,
                user.Avatar,
                user.CreatedAt,
                user.UpdatedAt, 
                user.IsActived,
                user.DepartmentID,
                user.Email,
                user.Phone,
                user.DisplayName,
                roles // 新增
            };

            await _logService.LogInfoAsync("获取当前用户信息成功", "UserController", new { Account = account, UserId = user.ID });
            return Ok(Tips<object>.Success(userInfo, "获取用户信息成功"));
        }
        catch (Exception ex)
        {
            await _logService.LogErrorAsync("获取当前用户信息异常", ex, "UserController");
            return Ok(Tips<string>.Fail("获取用户信息失败"));
        }
    }

    [HttpPost("upload-avatar")]
    [Microsoft.AspNetCore.Authorization.Authorize]
    public async Task<IActionResult> UploadAvatar([FromForm] IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("请选择图片");

        var uploads = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/avatars");
        if (!Directory.Exists(uploads))
            Directory.CreateDirectory(uploads);

        var fileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
        var filePath = Path.Combine(uploads, fileName);

        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }

        var url = $"/avatars/{fileName}";

        // 获取当前用户account
        var account = User.FindFirst(System.Security.Claims.ClaimTypes.Name)?.Value;
        if (string.IsNullOrEmpty(account))
            return Unauthorized();
        var user = await _service.GetUserAccount(account);
        if (user == null)
            return NotFound();

        user.Avatar = url;
        user.UpdatedAt = DateTime.UtcNow;
        await _service.UpdateUserAvatarAsync(user); // 新增：保存头像到数据库

        return Ok(Tips<object>.Success(new { url }, "头像上传成功"));
    }

    [HttpPut("profile")]
    [Microsoft.AspNetCore.Authorization.Authorize]
    public async Task<IActionResult> UpdateProfile([FromBody] UpdateProfileDto profileDto)
    {
        try
        {
            var account = User.FindFirst(System.Security.Claims.ClaimTypes.Name)?.Value;
            if (string.IsNullOrEmpty(account))
                return Ok(Tips<object>.Fail(new object(), 3474, "未找到用户信息"));

            var result = await _service.UpdateProfileAsync(account, profileDto);
            if (result == 0)
                return Ok(Tips<int>.Fail(result, 3474, "更新失败"));

            return Ok(Tips<int>.Success(result, "更新成功"));
        }
        catch (Exception ex)
        {
            return Ok(Tips<string>.Fail("更新失败"));
        }
    }

    public class ChangePasswordDto
    {
        public string CurrentPassword { get; set; }
        public string NewPassword { get; set; }
    }

    [HttpPost("change-password")]
    [Microsoft.AspNetCore.Authorization.Authorize]
    public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordDto dto)
    {
        var account = User.FindFirst(System.Security.Claims.ClaimTypes.Name)?.Value;
        if (string.IsNullOrEmpty(account))
            return Ok(Tips<object>.Fail(new object(), 3474, "未找到用户信息"));
        var user = await _service.GetUserAccount(account);
        if (user == null)
            return Ok(Tips<object>.Fail(new object(), 3474, "用户不存在"));
        var result = await _service.ChangePasswordAsync(user.ID, dto.CurrentPassword, dto.NewPassword);
        if (result == -1)
            return Ok(Tips<int>.Fail(result, 3474, "原密码错误"));
        if (result == 0)
            return Ok(Tips<int>.Fail(result, 3474, "修改失败"));
        return Ok(Tips<int>.Success(result, "修改成功"));
    }

    // public class SendResetCodeDto
    // {
    //     public string Account { get; set; }
    //     public string Phone { get; set; }
    // }
    // public class ResetPasswordDto
    // {
    //     public string Account { get; set; }
    //     public string Phone { get; set; }
    //     public string Code { get; set; }
    //     public string NewPassword { get; set; }
    // }

    // [HttpPost("send-reset-code")]
    // [Microsoft.AspNetCore.Authorization.AllowAnonymous]
    // public async Task<IActionResult> SendResetCode([FromBody] SendResetCodeDto dto)
    // {
    //     var user = await _service.GetUserAccount(dto.Account);
    //     if (user == null || user.Phone != dto.Phone)
    //         return Ok(Tips<string>.Fail("账号或手机号不正确"));
    //     var code = new Random().Next(100000, 999999).ToString();
    //     PasswordResetCodes.Codes[dto.Account] = (code, DateTime.UtcNow.AddMinutes(5));
    //     // 调用短信服务
    //     await _smsSender.SendAsync(dto.Phone, $"您的验证码是：{code}，5分钟内有效。");
    //     return Ok(Tips<string>.Success("验证码已发送", "验证码已发送"));
    // }

    // [HttpPost("reset-password")]
    // [Microsoft.AspNetCore.Authorization.AllowAnonymous]
    // public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordDto dto)
    // {
    //     // 校验验证码
    //     if (!PasswordResetCodes.Codes.TryGetValue(dto.Account, out var codeInfo) || codeInfo.Item1 != dto.Code || codeInfo.Item2 < DateTime.UtcNow)
    //         return Ok(Tips<string>.Fail("验证码无效或已过期"));
    //     var user = await _service.GetUserAccount(dto.Account);
    //     if (user == null || user.Phone != dto.Phone)
    //         return Ok(Tips<string>.Fail("账号或手机号不正确"));
    //     // 更新密码
    //     var pwdService = new PasswordService();
    //     var hash = pwdService.HashPassword(dto.NewPassword, out string salt);
    //     user.Password = hash;
    //     user.Salt = salt;
    //     user.UpdatedAt = DateTime.UtcNow;
    //     await _service.UpdateUserAvatarAsync(user); // 复用更新方法
    //     PasswordResetCodes.Codes.Remove(dto.Account);
    //     return Ok(Tips<string>.Success("重置成功"));
    // }
}